home *** CD-ROM | disk | FTP | other *** search
- /*
- * gethostnamadr.c
- *
- * Copyright (C) 1994 First Class Technology.
- */
-
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<errno.h>
-
- #include"tcpipdrv.h"
- #include"network.h"
- #include"socket.h"
-
- #define MAXHOSTADDR (15)
- #define MAXHOSTALIAS (15)
-
- static struct hostent _host;
- static unsigned char _hostname[127 + 1];
- static unsigned char *h_aliases[MAXHOSTALIAS + 1];
- static unsigned char *h_addr_list[MAXHOSTADDR + 1];
-
- static struct hostent *_gethostbyname (unsigned char *);
- static struct hostent *_gethostbyaddr (unsigned char *, int, int);
- static struct hostent *__gethostbyname (unsigned char *);
- static struct hostent *__gethostbyaddr (unsigned char *, int, int);
- static struct hostent * make_hostent (unsigned char *, int);
- static struct hostent *_copyhost (struct hostent *);
- static void free_hostent (void);
- static int add_addrs (long);
- static int add_aliases (unsigned char *);
- static unsigned short get16 (unsigned char *);
- static unsigned long get32 (unsigned char *);
- static unsigned char * get_dname (unsigned char **, unsigned char *);
-
- _ti_func search_ti_entry (void);
-
- /************************************************
- * *
- ************************************************/
- struct hostent *
- gethostbyname (char *name)
- {
- struct hostent *hp;
-
- hp = __gethostbyname ((unsigned char *)name);
- if (hp)
- return hp;
-
- hp = _gethostbyname ((unsigned char *)name);
- return _copyhost (hp);
- }
-
- /************************************************
- * *
- ************************************************/
- struct hostent *
- gethostbyaddr (char *adr, int len, int type)
- {
- struct hostent *hp;
-
- hp = __gethostbyaddr ((unsigned char *)adr, len, type);
- if (hp)
- return hp;
-
- hp = _gethostbyaddr ((unsigned char *)adr, len, type);
- return _copyhost (hp);
- }
-
- /************************************************
- * *
- ************************************************/
- static struct hostent *
- _gethostbyname (unsigned char *name)
- {
- _ti_func func = search_ti_entry ();
- if (func)
- return (struct hostent *)func (_TI_gethostbyname, (long *)name);
- return NULL;
- }
-
- /************************************************
- * *
- ************************************************/
- static struct hostent *
- _gethostbyaddr (unsigned char *addr, int len, int type)
- {
- _ti_func func = search_ti_entry ();
- if (func)
- {
- long argv[3];
-
- argv[0] = (long)addr;
- argv[1] = (long)len;
- argv[2] = (long)type;
-
- return (struct hostent *)func (_TI_gethostbyaddr, argv);
- }
- return NULL;
- }
-
- /************************************************
- * *
- ************************************************/
- static struct hostent *
- __gethostbyname (unsigned char *name)
- {
- unsigned char answer[2048];
- int anslen;
-
- anslen = res_search (name, C_IN, T_A, answer, sizeof (answer));
- if (anslen > 0)
- return make_hostent (answer, anslen);
- else
- return NULL;
- }
-
- /************************************************
- * *
- ************************************************/
- static struct hostent *
- __gethostbyaddr (unsigned char *addr, int len, int type)
- {
- unsigned char answer[2048], question[256];
- int anslen, qulen;
- struct hostent *tmp;
-
- if (type != AF_INET || len != sizeof (long))
- return NULL;
-
- #if 0 /* Inverse Query é═âLâââbâVâôâOé│éΩé╚éóé╠é┼ûΓéóìçéφé╣é≡ìsé╚éφé╚éó */
- /* Inverse Query */
- qulen = res_mkquery (IQUERY, NULL, C_IN, T_A, addr, sizeof (long),
- NULL, question, sizeof (question));
- if (qulen < 0)
- return NULL;
- anslen = res_send (question, qulen, answer, sizeof (answer));
- tmp = make_hostent (answer, anslen);
- if (tmp)
- return tmp;
- #endif
-
- {
- /* Query to in-addr.arpa */
- unsigned char buff[64];
-
- sprintf (buff, "%u.%u.%u.%u.in-addr.arpa",
- *(addr + 3), *(addr + 2), *(addr + 1), *addr);
-
- anslen = res_search (buff, C_IN, T_PTR, answer, sizeof (answer));
- if (anslen > 0)
- return make_hostent (answer, anslen);
- }
- return NULL;
- }
-
- /************************************************
- * *
- ************************************************/
- static struct hostent *
- make_hostent (unsigned char *answer, int len)
- {
- int n_q, n_a, i;
- unsigned char *p;
-
- p = answer;
- p += 4;
- n_q = get16 (p); p += 2;
- n_a = get16 (p); p += 6;
-
- if (!(n_q && n_a))
- return NULL;
-
- _host.h_name = _hostname;
- _host.h_aliases = (char **)h_aliases;
- _host.h_addr_list = (char **)h_addr_list;
-
- free_hostent ();
-
- for (i = 0; i < n_q; i++)
- {
- int class, type;
- unsigned char *dname;
-
- dname = get_dname (&p, answer);
- type = get16 (p); p += 2;
- class = get16 (p); p += 2;
-
- if (class == C_IN && type == T_A)
- strcpy (_hostname, dname); /* hostname or cname or inverse query*/
- free (dname);
- }
-
- for (i = 0; i < n_a; i++)
- {
- int class, type, ttl, length;
- unsigned char *dname;
-
- dname = get_dname (&p, answer);
-
- type = get16 (p); p += 2;
- class = get16 (p); p += 2;
- ttl = get32 (p); p += 4;
- length = get16 (p); p += 2;
-
- if (class == C_IN)
- {
- switch (type)
- {
- case T_A:
- {
- long a;
-
- a = get32 (p); p += 4;
-
- if (add_addrs (a))
- {
- free_hostent ();
- free (dname);
- return NULL;
- }
- }
- break;
- case T_PTR:
- {
- unsigned int num[4];
- int result;
- long a;
-
- result = sscanf (dname, "%u.%u.%u.%u.in-addr.arpa",
- num + 3, num + 2, num + 1, num);
- if (result != 4)
- {
- free_hostent ();
- free (dname);
- return NULL;
- }
- a = (((num[0] & 0xff) << 24) + ((num[1] & 0xff) << 16)
- + ((num[2] & 0xff) << 8) + (num[3] & 0xff));
- if (add_addrs (a))
- {
- free_hostent ();
- free (dname);
- return NULL;
- }
- free (dname);
- dname = get_dname (&p, answer);
- strcpy (_hostname, dname);
- }
- break;
- case T_CNAME:
- if (add_aliases (dname))
- {
- free_hostent ();
- free (dname);
- return NULL;
- }
- free (dname);
- dname = get_dname (&p, answer);
- strcpy (_hostname, dname);
- break;
- default:
- p += length;
- break;
- }
- }
- else
- p += length;
- free (dname);
- }
-
- if (!*_hostname || (!*h_aliases && !*h_addr_list))
- {
- free_hostent ();
- return NULL;
- }
-
- return &_host;
- }
-
- /************************************************
- * *
- ************************************************/
- static void
- free_hostent (void)
- {
- unsigned char **cur;
-
- /* free memory that was allocated */
- if (_host.h_aliases)
- {
- cur = (unsigned char **)_host.h_aliases;
-
- while (*cur)
- {
- free (*cur);
- *cur++ = NULL;
- }
- }
- if (_host.h_addr_list)
- {
- cur = (unsigned char **)_host.h_addr_list;
-
- while (*cur)
- {
- free (*cur);
- *cur++ = NULL;
- }
- }
- return;
- }
-
- /************************************************
- * *
- ************************************************/
- static struct hostent *
- _copyhost (struct hostent *src)
- {
- unsigned char **cur, *addr, *alias;
- int n_addr, n_alias, addr_size, alias_size, addr_len;
-
- if (!src)
- return NULL;
-
- free_hostent ();
-
- /* calc new alias and addrs */
- n_alias = 0; alias_size = 0;
- if (src->h_aliases)
- {
- cur = (unsigned char **)src->h_aliases;
- while (*cur)
- {
- n_alias++;
- alias_size += strlen (*cur++) + 1;
- }
- }
- if (n_alias > MAXHOSTALIAS)
- n_alias = MAXHOSTALIAS;
-
- n_addr = 0; addr_size = 0;
- if (src->h_addr_list)
- {
- cur = (unsigned char **)src->h_addr_list;
- while (*cur++)
- n_addr++;
- }
- if (n_addr > MAXHOSTADDR)
- n_addr = MAXHOSTADDR;
- addr_len = src->h_length;
- addr_size = n_addr * addr_len;
-
- /* malloc */
- alias = malloc (alias_size);
- if (!alias)
- {
- errno = ENOMEM;
- return NULL;
- }
- addr = malloc (addr_size);
- if (!addr)
- {
- free (alias);
- errno = ENOMEM;
- return NULL;
- }
-
- /* make list */
- {
- unsigned char **p, *q;
-
- p = h_aliases;
- q = alias;
- cur = (unsigned char **)src->h_aliases;
- while (*cur)
- {
- *p++ = q;
- strcpy (q, *cur);
- while (*q++)
- ;
- cur++;
- }
- *p = NULL;
-
- p = h_addr_list;
- q = addr;
- cur = (unsigned char **)src->h_addr_list;
- while (*cur)
- {
- *p++ = q;
- memcpy (q, *cur, addr_len);
- q += addr_len;
- cur++;
- }
- *p = NULL;
- }
- memcpy (&_host, src, sizeof (struct hostent));
- strcpy (_hostname, src->h_name);
- _host.h_name = _hostname;
- _host.h_aliases = (char **)h_aliases;
- _host.h_addr_list = (char **)h_addr_list;
-
- return &_host;
- }
-
- /************************************************
- * *
- ************************************************/
- static int
- add_addrs (long a)
- {
- long *q, **qq;
-
- q = malloc (sizeof (long));
- if (!q)
- return -1;
- *q = a;
-
- /* search vector */
- qq = (long **)h_addr_list;
- while (*qq++)
- ;
- *(qq - 1) = q;
-
- return 0;
- }
-
- /************************************************
- * *
- ************************************************/
- static int
- add_aliases (unsigned char *a)
- {
- unsigned char *q, **qq;
- int size;
-
- if (!a)
- return 0;
-
- size = strlen (a);
- q = malloc (size + 1);
- if (!q)
- return -1;
- strcpy (q, a);
-
- /* search vector */
- qq = h_aliases;
- while (*qq++)
- ;
- *(qq - 1) = q;
-
- return 0;
- }
-
- /************************************************
- * *
- ************************************************/
- static unsigned short
- get16 (unsigned char *p)
- {
- unsigned short a;
-
- a = ((*p & 0xff) << 8) + (*(p + 1) & 0xff);
-
- return a;
- }
-
- /************************************************
- * *
- ************************************************/
- static unsigned long
- get32 (unsigned char *p)
- {
- unsigned long a;
-
- a = (((*p & 0xff) << 24) + ((*(p + 1) & 0xff) << 16)
- + ((*(p + 2) & 0xff) << 8) + (*(p + 3) & 0xff));
- return a;
- }
-
- /************************************************
- * *
- ************************************************/
- static int
- strlen_dname (unsigned char *src, unsigned char *top)
- {
- /* calc size */
- unsigned char *q;
- int size, size2;
-
- q = src;
- size = 0;
- while ((size2 = (unsigned int)(*q++ & 0xff)))
- {
- if ((size2 & 0xc0) == 0xc0)
- {
- size += strlen_dname (top + (unsigned int)*q++, top);
- break;
- }
- else
- {
- size += size2 + 1;
- q += size2;
- }
- }
-
- return size;
- }
-
- /************************************************
- * *
- ************************************************/
- static unsigned char *
- get_dname (unsigned char **src, unsigned char *top)
- {
- unsigned char *q, *p, *pp;
- int size, size2;
-
- /* calc size */
- size = strlen_dname (*src, top);
-
- pp = p = malloc (size);
- if (!p)
- return NULL;
-
- /* copy */
- q = *src;
- size = 0;
- while ((size2 = (unsigned int)(*q++ & 0xff)))
- {
- if ((size2 & 0xc0) == 0xc0)
- {
- char *dname2;
- unsigned char *tmp;
-
- tmp = top + *q++;
- dname2 = get_dname (&tmp, top);
- if (dname2)
- {
- strcpy (pp, dname2);
- while (*pp++)
- ;
- free (dname2);
- }
- break;
- }
- else
- {
- memcpy (pp, q, size2);
- pp += size2;
- *pp++ = '.';
- q += size2;
- }
- }
- *(pp - 1) = '\0';
- *src = q;
- return p;
- }
-